/*
 * @Author: aggfb 714740235@qq.com
 * @Date: 2024-10-01 10:22:33
 * @LastEditors: aggfb 714740235@qq.com
 * @LastEditTime: 2024-10-01 18:42:00
 * @FilePath: \baking_machine\bsp\bsp_adc.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "bsp_adc.h"

uint16_t adc0_buff[1] = {0};

static void bsp_adc01_init(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_ADC0);
    rcu_periph_clock_enable(RCU_ADC1);
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
    // GPIO配置
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2); // M0
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6); // M1
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_7);                           // M2
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_4 | GPIO_PIN_5);
    gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0); // 母线电压
    // 共同属性配置
    adc_mode_config(ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL);   // 规则组和组入组并行
    // ADC0 
    adc_deinit(ADC0);
    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);       // 扫描模式
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE); // 连续
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);           // 右对齐    
    // ADC1 
    adc_deinit(ADC1);
    adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);       // 扫描模式
    adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, ENABLE); // 连续
    adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);           // 右对齐   

    // ADC0 规则组设置
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL,1);
    adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_8, ADC_SAMPLETIME_7POINT5);     // 母线电压
    // (M2: <W V U> )
    #if 0 
    adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_7, ADC_SAMPLETIME_7POINT5);  // M2 W
    adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_14, ADC_SAMPLETIME_7POINT5); // M2 V
    adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_15, ADC_SAMPLETIME_7POINT5); // M2 U
    #endif
    adc_dma_mode_enable(ADC0);
    // ADC0 规则组 外部触发使能
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); // 软件触发规则组采样
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    // ADC0 注入组设置
    // (M0: <W V U> + M1 :<W>)
    adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 4);
    adc_inserted_channel_config(ADC0, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_7POINT5); // M0 W
    adc_inserted_channel_config(ADC0, 1, ADC_CHANNEL_11, ADC_SAMPLETIME_7POINT5); // M0 V
    adc_inserted_channel_config(ADC0, 2, ADC_CHANNEL_12, ADC_SAMPLETIME_7POINT5); // M0 U
    adc_inserted_channel_config(ADC0, 3, ADC_CHANNEL_7,  ADC_SAMPLETIME_7POINT5); // M2 W
    // ADC0 注入组 外部触发使能
    adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC0_1_EXTTRIG_INSERTED_T0_TRGO); // 定时器TRGO触发

    // ADC1 注入组设置
    // (M1: <W V U> + )
    adc_channel_length_config(ADC1, ADC_INSERTED_CHANNEL, 4);
    adc_inserted_channel_config(ADC1, 0, ADC_CHANNEL_4, ADC_SAMPLETIME_7POINT5); // M1 W
    adc_inserted_channel_config(ADC1, 1, ADC_CHANNEL_5, ADC_SAMPLETIME_7POINT5); // M1 V
    adc_inserted_channel_config(ADC1, 2, ADC_CHANNEL_6, ADC_SAMPLETIME_7POINT5); // M1 U
    adc_inserted_channel_config(ADC1, 3, ADC_CHANNEL_14, ADC_SAMPLETIME_7POINT5); // M2 V

    // 外部触发使能    
    adc_external_trigger_source_config(ADC1, ADC_INSERTED_CHANNEL, ADC0_1_2_EXTTRIG_INSERTED_NONE);
    
    adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
    adc_external_trigger_config(ADC1, ADC_INSERTED_CHANNEL, ENABLE);

    adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);
    adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);

    adc_interrupt_enable(ADC0, ADC_INT_EOIC); // 注入组转换中断
    nvic_irq_enable(ADC0_1_IRQn, 5, 0);

    adc_enable(ADC0);
    for (uint32_t i = 0; i < 120000; i++);
    adc_calibration_enable(ADC0);

    adc_enable(ADC1);
    for (uint32_t i = 0; i < 120000; i++);   
    adc_calibration_enable(ADC1);

    // 触发规则组采样
    for (uint32_t i = 0; i < 240000; i++);   
    adc_software_trigger_enable(ADC0, ADC_REGULAR_INSERTED_CHANNEL);
}

/**
 * adc0 规则组adc采样 dma
 */
static void bsp_adc0_dma0_ch0_init(void)
{
    dma_parameter_struct dma_init_struct;
    rcu_periph_clock_enable(RCU_DMA0);

    dma_deinit(DMA0, DMA_CH0);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
    dma_init_struct.memory_addr = (uint32_t)(adc0_buff);
    dma_init_struct.number = 1;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;   
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH0, &dma_init_struct);
    dma_circulation_enable(DMA0, DMA_CH0);
    dma_channel_enable(DMA0, DMA_CH0);
}

void bsp_adc_init(void)
{
    bsp_adc01_init();
    bsp_adc0_dma0_ch0_init();
}
